// 复杂类型
var a = { id: 1 }
var c = a;
c.id = 2;
console.log(a.id)
// 基本类型
var a = 1;
var b = a;
b = 2;
console.log(a)
// 浅拷贝
var a = {
    id: 1
}
// var c = Object.assign({}, a);  都会返回一个新对象
var c = { ...a };
c.id = 2;
console.log(a.id); // 如何让a.id不变
// 深拷贝
var a = {
    data: {
        id: 1
    }
}
var c = JSON.parse(JSON.stringify(a)); // 返回一个全新的对象
// 深拷贝方案  递归遍历法
c.data.id = 2;
console.log(a.data.id)

// this指向
// 普通函数 指向调用者
// 箭头函数 继承当前上下文的this
// 如何改变this指向
// call apply 改变指向并调用函数
// bind 只改变this指向


// 什么是作用域
// ES5的作用域和 ES6的作用域分别如何实现
// ES5
// function() {}
// ES6
// () => {}
// {let const}  只要使用了 let const 就会产生作用域

// var a = 1;
function app() {
    var b = 2;
    console.log(a) // 先从自身作用域找 一直找到window 如果还没有就报未定义 a is not defined
}
console.log(b)
// 只能由内而外 不能由外而内
app();

// 原型链
// 1. 每个构造函数都有一个显示原型 prototype
// 2. 每个对象都有一个 隐式原型 __proto__
// 3. 每个对象的隐式原型都指向它构造函数的显示原型
var a = {}; // new Object()
// 访问a.id做了哪些步骤
// 自身查找有没有id => __proto__ => Object.prototype => Object.prototype.__proto__ => null 原型链

function App() {

}
App.prototype.id = 1;
var app = new App();
// app.id
// 自身=> app.__proto__ => App.prototype (new Object) =>App.prototype.__proto__=>Object.prototype=>Object.prototype.__proto=>null